(ns liberator-sample.core.tutorial.handling-post
  (:require [liberator.core :refer [defresource resource]]
            [liberator.dev :refer [wrap-trace]]
            [compojure.core :refer [defroutes ANY]]
            [ring.middleware.params :refer [wrap-params]]
            [ring.middleware.json :refer [wrap-json-response]]
            [org.httpkit.server :as server])
  (:use clojure.pprint))

(def posts (ref []))

(declare app x)
(defroutes app
           (ANY "/postbox" []
                (resource
                  :allowed-methods [:post :get]
                  :available-media-types ["text/html"]
                  :handle-ok (fn [_]
                               (format (str "<html>Post text/plain to this resource.<br>\n"
                                            "There are %d posts at the moment.</html>")
                                       (count @posts)))
                  :post! (fn [ctx]
                           (dosync
                             (let [body (slurp (get-in ctx [:request :body]))
                                   id (count (alter posts conj body))]
                               (println "post" id)
                               {::id id})))
                  :post-redirect? (fn [ctx]
                                    {:location (format "/postbox/%s" (::id ctx))})))

           (ANY "/cond-postbox" []
                (resource
                  :allowed-methods [:post :get]
                  :available-media-types ["text/html"]
                  :handle-ok (fn [ctx]
                               (format (str "<html>Post text/plain to this resource.<br>\n"
                                            "There are %d posts at the moment.")
                                       (count @posts)))
                  :post! (fn [ctx]
                           (dosync
                             (let [body (slurp (get-in ctx [:request :body]))
                                   id (count (alter posts conj body))]
                               (println "cond-post" id)
                               {::id id})))
                  :post-redirect? (fn [ctx]
                                    {:location (format "/postbox/%s" (::id ctx))})
                  :etag (fn [_] (str (count @posts)))))

           (ANY "/postbox/:x" [x]
                (resource
                  :allowed-methods [:get]
                  :available-media-types ["application/json"]
                  :exists? (fn [_]
                             (println "get" x)
                             (if-let [d (get @posts (dec (Integer/parseInt x)))]
                               {::data [d]}))
                  :handle-ok ::data)))

(server/run-server (wrap-json-response app :pretty true) {:port 3333})